home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 23 / CU Amiga - Super CD-ROM 23 (June 1998).iso / CreatingGames / Utilities / C / Mesa / src / xmesa3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-13  |  56.4 KB  |  1,933 lines

  1. /* $Id: xmesa3.c,v 1.12 1997/01/31 23:45:19 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.0
  6.  * Copyright (C) 1995-1996  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: xmesa3.c,v $
  26.  * Revision 1.12  1997/01/31 23:45:19  brianp
  27.  * faster flat-shaded dithered triangles from code by Martin Schenk (schenkm@ping.at)
  28.  *
  29.  * Revision 1.11  1996/11/30 15:13:26  brianp
  30.  * added some parenthesis to WINCLIP macros
  31.  *
  32.  * Revision 1.10  1996/11/02 06:17:02  brianp
  33.  * removed some unused local vars
  34.  *
  35.  * Revision 1.9  1996/10/22 02:59:12  brianp
  36.  * incorporated Micheal Pichler's X line stipple patches
  37.  *
  38.  * Revision 1.8  1996/10/22 02:48:18  brianp
  39.  * now use DITHER_SETUP and XDITHER macros
  40.  * use array indexing instead of pointer dereferencing in inner loops
  41.  *
  42.  * Revision 1.7  1996/10/11 03:43:03  brianp
  43.  * add LineZoffset factor to window Z coords
  44.  *
  45.  * Revision 1.6  1996/10/01 03:31:30  brianp
  46.  * use new FixedToDepth() macro
  47.  *
  48.  * Revision 1.5  1996/09/27 01:31:54  brianp
  49.  * removed unused variables
  50.  *
  51.  * Revision 1.4  1996/09/25 02:02:59  brianp
  52.  * coordinates were incorrectly biased in flat_pixmap_triangle()
  53.  *
  54.  * Revision 1.3  1996/09/19 03:16:04  brianp
  55.  * new X/Mesa interface with XMesaContext, XMesaVisual, and XMesaBuffer types
  56.  *
  57.  * Revision 1.2  1996/09/15 14:21:43  brianp
  58.  * now use GLframebuffer and GLvisual
  59.  *
  60.  * Revision 1.1  1996/09/13 01:38:16  brianp
  61.  * Initial revision
  62.  *
  63.  */
  64.  
  65.  
  66. /*
  67.  * Mesa/X11 interface, part 3.
  68.  *
  69.  * This file contains "accelerated" point, line, and triangle functions.
  70.  * It should be fairly easy to write new special-purpose point, line or
  71.  * triangle functions and hook them into this module.
  72.  */
  73.  
  74.  
  75.  
  76. #include <sys/time.h>
  77. #include <assert.h>
  78.  
  79.  
  80. #include <stdlib.h>
  81. #include <stdio.h>
  82. #include <X11/Xlib.h>
  83. #include "bresenhm.h"
  84. #include "depth.h"
  85. #include "interp.h"
  86. #include "macros.h"
  87. #include "vb.h"
  88. #include "types.h"
  89. #include "xmesaP.h"
  90.  
  91.  
  92. /*
  93.  * Like PACK_8A8B8G8R() but don't use alpha.  This is usually an acceptable
  94.  * shortcut.
  95.  */
  96. #define PACK_8B8G8R( R, G, B )   ( ((B) << 16) | ((G) << 8) | (R) )
  97.  
  98.  
  99.  
  100.  
  101. /**********************************************************************/
  102. /***                    Point rendering                             ***/
  103. /**********************************************************************/
  104.  
  105.  
  106. /*
  107.  * Render an array of points into a pixmap, any pixel format.
  108.  */
  109. static void draw_points_ANY_pixmap( GLcontext *ctx, GLuint first, GLuint last )
  110. {
  111.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  112.    Display *dpy = xmesa->xm_visual->display;
  113.    Drawable buffer = xmesa->xm_buffer->buffer;
  114.    GC gc = xmesa->xm_buffer->gc2;
  115.    struct vertex_buffer *VB = ctx->VB;
  116.    register GLuint i;
  117.  
  118.    if (VB->MonoColor) {
  119.       /* all same color */
  120.       XPoint p[VB_SIZE];
  121.       int n = 0;
  122.       for (i=first;i<=last;i++) {
  123.          if (VB->Unclipped[i]) {
  124.             p[n].x =       (GLint) VB->Win[i][0];
  125.             p[n].y = FLIP( (GLint) VB->Win[i][1] );
  126.             n++;
  127.          }
  128.       }
  129.       XDrawPoints( dpy, buffer, xmesa->xm_buffer->gc1, p, n, CoordModeOrigin );
  130.    }
  131.    else {
  132.       /* all different colors */
  133.       int shift = ctx->ColorShift;
  134.       if (xmesa->xm_visual->gl_visual->RGBAflag) {
  135.          /* RGB mode */
  136.          for (i=first;i<=last;i++) {
  137.             if (VB->Unclipped[i]) {
  138.                register int x, y;
  139.                unsigned long pixel = xmesa_color_to_pixel( xmesa,
  140.                                                 VB->Color[i][0] >> shift,
  141.                                                 VB->Color[i][1] >> shift,
  142.                                                 VB->Color[i][2] >> shift,
  143.                                                 VB->Color[i][3] >> shift );
  144.                XSetForeground( dpy, gc, pixel );
  145.                x =       (GLint) VB->Win[i][0];
  146.                y = FLIP( (GLint) VB->Win[i][1] );
  147.                XDrawPoint( dpy, buffer, gc, x, y);
  148.             }
  149.          }
  150.       }
  151.       else {
  152.          /* Color index mode */
  153.          for (i=first;i<=last;i++) {
  154.             if (VB->Unclipped[i]) {
  155.                register int x, y;
  156.                XSetForeground( dpy, gc, VB->Index[i] >> shift );
  157.                x =       (GLint) VB->Win[i][0];
  158.                y = FLIP( (GLint) VB->Win[i][1] );
  159.                XDrawPoint( dpy, buffer, gc, x, y);
  160.             }
  161.          }
  162.       }
  163.    }
  164. }
  165.  
  166.  
  167.  
  168. /*
  169.  * Analyze context state to see if we can provide a fast points drawing
  170.  * function, like those in points.c.  Otherwise, return NULL.
  171.  */
  172. points_func xmesa_get_points_func( GLcontext *ctx )
  173. {
  174.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  175.  
  176.    if (ctx->Point.Size==1.0F && !ctx->Point.SmoothFlag && ctx->RasterMask==0
  177.        && !ctx->Texture.Enabled) {
  178.       if (xmesa->xm_buffer->buffer==XIMAGE) {
  179.          return NULL; /*draw_points_ximage;*/
  180.       }
  181.       else {
  182.          return draw_points_ANY_pixmap;
  183.       }
  184.    }
  185.    else {
  186.       return NULL;
  187.    }
  188. }
  189.  
  190.  
  191.  
  192. /**********************************************************************/
  193. /***                      Line rendering                            ***/
  194. /**********************************************************************/
  195.  
  196. /*
  197.  * Render a line into a pixmap, any pixel format.
  198.  */
  199. static void flat_pixmap_line( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
  200. {
  201.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  202.    struct vertex_buffer *VB = ctx->VB;
  203.    register int x0, y0, x1, y1;
  204.    GC gc;
  205.    if (VB->MonoColor) {
  206.       gc = xmesa->xm_buffer->gc1;  /* use current color */
  207.    }
  208.    else {
  209.       unsigned long pixel;
  210.       if (xmesa->xm_visual->gl_visual->RGBAflag) {
  211.          pixel = xmesa_color_to_pixel( xmesa,
  212.                                        VB->Color[pv][0], VB->Color[pv][1],
  213.                                        VB->Color[pv][2], VB->Color[pv][3] );
  214.       }
  215.       else {
  216.          pixel = VB->Index[pv];
  217.       }
  218.       gc = xmesa->xm_buffer->gc2;
  219.       XSetForeground( xmesa->display, gc, pixel );
  220.    }
  221.    x0 =       (GLint) VB->Win[v0][0];
  222.    y0 = FLIP( (GLint) VB->Win[v0][1] );
  223.    x1 =       (GLint) VB->Win[v1][0];
  224.    y1 = FLIP( (GLint) VB->Win[v1][1] );
  225.    XDrawLine( xmesa->display, xmesa->xm_buffer->buffer, gc, x0, y0, x1, y1 );
  226. }
  227.  
  228.  
  229. /*
  230.  * Despite being clipped to the view volume, the line's window coordinates
  231.  * may just lie outside the window bounds.  That is, if the legal window
  232.  * coordinates are [0,W-1][0,H-1], it's possible for x==W and/or y==H.
  233.  * These quick and dirty macros take care of that possibility.
  234.  */
  235. #define WINCLIP_X(X1,X2)        \
  236.    {                    \
  237.       GLint w = ctx->Buffer->Width;    \
  238.       if ((X1==w) | (X2==w)) {        \
  239.          if ((X1==w) & (X2==w))  return;\
  240.          X1 -= (X1==w);   X2 -= (X2==w);\
  241.       }                    \
  242.    }
  243.  
  244. #define WINCLIP_Y(Y1,Y2)        \
  245.    {                    \
  246.       GLint h = ctx->Buffer->Height;    \
  247.       if ((Y1==h) | (Y2==h)) {        \
  248.          if ((Y1==h) & (Y2==h))  return;\
  249.          Y1 -= (Y1==h);   Y2 -= (Y2==h);\
  250.       }                    \
  251.    }
  252.  
  253.  
  254. /*
  255.  * Draw a flat-shaded, PF_8A8B8G8R line into an XImage.
  256.  */
  257. static void flat_8A8B8G8R_line( GLcontext *ctx,
  258.                                 GLuint v0, GLuint v1, GLuint pv )
  259. {
  260.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  261.    struct vertex_buffer *VB = ctx->VB;
  262.    GLint x1 = (GLint) VB->Win[v0][0],  y1 = (GLint) VB->Win[v0][1];
  263.    GLint x2 = (GLint) VB->Win[v1][0],  y2 = (GLint) VB->Win[v1][1];
  264.    GLuint pixel;
  265.    WINCLIP_X(x1,x2);
  266.    WINCLIP_Y(y1,y2);
  267.    pixel = PACK_8B8G8R( VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2] );
  268.  
  269. #define BRESENHAM_PLOT(X,Y)            \
  270.     {                    \
  271.        GLuint *ptr = PIXELADDR4(X,Y);    \
  272.        *ptr = pixel;            \
  273.     }
  274.  
  275.    BRESENHAM( x1, y1, x2, y2 );
  276.  
  277. #undef BRESENHAM_PLOT
  278. }
  279.  
  280.  
  281. /*
  282.  * Draw a flat-shaded, PF_8R8G8B line into an XImage.
  283.  */
  284. static void flat_8R8G8B_line( GLcontext *ctx,
  285.                               GLuint v0, GLuint v1, GLuint pv )
  286. {
  287.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  288.    struct vertex_buffer *VB = ctx->VB;
  289.    GLint x1 = (GLint) VB->Win[v0][0],  y1 = (GLint) VB->Win[v0][1];
  290.    GLint x2 = (GLint) VB->Win[v1][0],  y2 = (GLint) VB->Win[v1][1];
  291.    GLuint pixel;
  292.    WINCLIP_X(x1,x2);
  293.    WINCLIP_Y(y1,y2);
  294.    pixel = PACK_8R8G8B( VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2] );
  295.  
  296. #define BRESENHAM_PLOT(X,Y)            \
  297.     {                    \
  298.        GLuint *ptr = PIXELADDR4(X,Y);    \
  299.        *ptr = pixel;            \
  300.     }
  301.  
  302.    BRESENHAM( x1, y1, x2, y2 );
  303.  
  304. #undef BRESENHAM_PLOT
  305. }
  306.  
  307.  
  308. /*
  309.  * Draw a flat-shaded, PF_5R6G5B line into an XImage.
  310.  */
  311. static void flat_5R6G5B_line( GLcontext *ctx,
  312.                               GLuint v0, GLuint v1, GLuint pv )
  313. {
  314.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  315.    struct vertex_buffer *VB = ctx->VB;
  316.    GLint x1 = (GLint) VB->Win[v0][0],  y1 = (GLint) VB->Win[v0][1];
  317.    GLint x2 = (GLint) VB->Win[v1][0],  y2 = (GLint) VB->Win[v1][1];
  318.    GLushort pixel;
  319.    WINCLIP_X(x1,x2);
  320.    WINCLIP_Y(y1,y2);
  321.    pixel = PACK_5R6G5B( VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2] );
  322.  
  323. #define BRESENHAM_PLOT(X,Y)            \
  324.     {                    \
  325.        GLushort *ptr = PIXELADDR2(X,Y);    \
  326.        *ptr = pixel;            \
  327.     }
  328.  
  329.    BRESENHAM( x1, y1, x2, y2 );
  330.  
  331. #undef BRESENHAM_PLOT
  332. }
  333.  
  334.  
  335.  
  336. /*
  337.  * Draw a flat-shaded, PF_TRUECOLOR line into an XImage.
  338.  */
  339. static void flat_TRUECOLOR_line( GLcontext *ctx,
  340.                                  GLuint v0, GLuint v1, GLuint pv )
  341. {
  342.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  343.    struct vertex_buffer *VB = ctx->VB;
  344.    XImage *img = xmesa->xm_buffer->backimage;
  345.    GLint x1 = (GLint) VB->Win[v0][0], y1 = (GLint) VB->Win[v0][1];
  346.    GLint x2 = (GLint) VB->Win[v1][0], y2 = (GLint) VB->Win[v1][1];
  347.    unsigned long pixel = PACK_RGB( VB->Color[pv][0], VB->Color[pv][1],
  348.                                    VB->Color[pv][2] );
  349.    WINCLIP_X(x1,x2);
  350.    WINCLIP_Y(y1,y2);
  351.  
  352. #define BRESENHAM_PLOT(X,Y)                    \
  353.         XPutPixel( img, X, FLIP(Y), pixel );
  354.  
  355.    BRESENHAM( x1, y1, x2, y2 );
  356.  
  357. #undef BRESENHAM_PLOT
  358. }
  359.  
  360.  
  361. /*
  362.  * Draw a flat-shaded, PF_DITHER 8-bit line into an XImage.
  363.  */
  364. static void flat_DITHER8_line( GLcontext *ctx,
  365.                                GLuint v0, GLuint v1, GLuint pv )
  366. {
  367.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  368.    struct vertex_buffer *VB = ctx->VB;
  369.    GLint x1 = (GLint) VB->Win[v0][0], y1 = (GLint) VB->Win[v0][1];
  370.    GLint x2 = (GLint) VB->Win[v1][0], y2 = (GLint) VB->Win[v1][1];
  371.    GLint r = VB->Color[pv][0], g = VB->Color[pv][1], b = VB->Color[pv][2];
  372.    DITHER_SETUP;
  373.  
  374.    WINCLIP_X(x1,x2);
  375.    WINCLIP_Y(y1,y2);
  376.  
  377. #define BRESENHAM_PLOT(X,Y)               \
  378.     GLubyte *ptr = PIXELADDR1(X,Y);    \
  379.     *ptr = DITHER( X, Y, r, g, b);
  380.  
  381.    BRESENHAM( x1, y1, x2, y2 );
  382.  
  383. #undef BRESENHAM_PLOT
  384. }
  385.  
  386.  
  387. /*
  388.  * Draw a flat-shaded, PF_LOOKUP 8-bit line into an XImage.
  389.  */
  390. static void flat_LOOKUP8_line( GLcontext *ctx,
  391.                                GLuint v0, GLuint v1, GLuint pv )
  392. {
  393.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  394.    struct vertex_buffer *VB = ctx->VB;
  395.    GLint x1 = (GLint) VB->Win[v0][0], y1 = (GLint) VB->Win[v0][1];
  396.    GLint x2 = (GLint) VB->Win[v1][0], y2 = (GLint) VB->Win[v1][1];
  397.    LOOKUP_SETUP;
  398.    GLubyte pixel = LOOKUP( VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2] );
  399.  
  400.    WINCLIP_X(x1,x2);
  401.    WINCLIP_Y(y1,y2);
  402.  
  403. #define BRESENHAM_PLOT(X,Y)               \
  404.     GLubyte *ptr = PIXELADDR1(X,Y);    \
  405.     *ptr = pixel;
  406.  
  407.    BRESENHAM( x1, y1, x2, y2 );
  408.  
  409. #undef BRESENHAM_PLOT
  410. }
  411.  
  412.  
  413. /*
  414.  * Draw a flat-shaded, PF_HPCR line into an XImage.
  415.  */
  416. static void flat_HPCR_line( GLcontext *ctx,
  417.                             GLuint v0, GLuint v1, GLuint pv )
  418. {
  419.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  420.    struct vertex_buffer *VB = ctx->VB;
  421.    GLint x1 = (GLint) VB->Win[v0][0], y1 = (GLint) VB->Win[v0][1];
  422.    GLint x2 = (GLint) VB->Win[v1][0], y2 = (GLint) VB->Win[v1][1];
  423.    GLint r = VB->Color[pv][0], g = VB->Color[pv][1], b = VB->Color[pv][2];
  424.  
  425.    WINCLIP_X(x1,x2);
  426.    WINCLIP_Y(y1,y2);
  427.  
  428. #define BRESENHAM_PLOT(X,Y)            \
  429.     GLubyte *ptr = PIXELADDR1(X,Y);        \
  430.     *ptr = DITHER_HPCR( X, Y, r, g, b);
  431.  
  432.    BRESENHAM( x1, y1, x2, y2 );
  433.  
  434. #undef BRESENHAM_PLOT
  435. }
  436.  
  437.  
  438.  
  439. /*
  440.  * Draw a flat-shaded, Z-less, PF_TRUECOLOR line into an XImage.
  441.  */
  442. static void flat_TRUECOLOR_z_line( GLcontext *ctx,
  443.                                    GLuint v0, GLuint v1, GLuint pv )
  444. {
  445.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  446.    XImage *img = xmesa->xm_buffer->backimage;
  447.    struct vertex_buffer *VB = ctx->VB;
  448.    GLint x1 = (GLint) VB->Win[v0][0], x2 = (GLint) VB->Win[v1][0];
  449.    GLint y1 = (GLint) VB->Win[v0][1], y2 = (GLint) VB->Win[v1][1];
  450.    GLint z1 = (GLint) (VB->Win[v0][2] + ctx->LineZoffset);
  451.    GLint z2 = (GLint) (VB->Win[v1][2] + ctx->LineZoffset);
  452.    unsigned long pixel = PACK_RGB( VB->Color[pv][0], VB->Color[pv][1],
  453.                                    VB->Color[pv][2] );
  454.  
  455.    WINCLIP_X(x1,x2);
  456.    WINCLIP_Y(y1,y2);
  457.  
  458. #define BRESENHAM_PLOT(X,Y,Z,ZBUF)        \
  459.     if (Z < *ZBUF) {            \
  460.            XPutPixel( img, X, FLIP(Y), pixel );    \
  461.        *ZBUF = Z;                \
  462.     }
  463.  
  464.    BRESENHAM_Z( ctx, x1, y1, z1, x2, y2, z2 );
  465.  
  466. #undef BRESENHAM_PLOT
  467. }
  468.  
  469.  
  470. /*
  471.  * Draw a flat-shaded, Z-less, PF_8A8B8G8R line into an XImage.
  472.  */
  473. static void flat_8A8B8G8R_z_line( GLcontext *ctx,
  474.                                   GLuint v0, GLuint v1, GLuint pv )
  475. {
  476.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  477.    struct vertex_buffer *VB = ctx->VB;
  478.    GLint x1 = (GLint) VB->Win[v0][0], x2 = (GLint) VB->Win[v1][0];
  479.    GLint y1 = (GLint) VB->Win[v0][1], y2 = (GLint) VB->Win[v1][1];
  480.    GLint z1 = (GLint) (VB->Win[v0][2] + ctx->LineZoffset);
  481.    GLint z2 = (GLint) (VB->Win[v1][2] + ctx->LineZoffset);
  482.    GLuint pixel = PACK_8B8G8R( VB->Color[pv][0], VB->Color[pv][1],
  483.                                VB->Color[pv][2] );
  484.  
  485.    WINCLIP_X(x1,x2);
  486.    WINCLIP_Y(y1,y2);
  487.  
  488. #define BRESENHAM_PLOT(X,Y,Z,ZBUF)        \
  489.     if (Z < *ZBUF) {            \
  490.        GLuint *ptr = PIXELADDR4(X,Y);    \
  491.        *ptr = pixel;            \
  492.        *ZBUF = Z;                \
  493.     }
  494.  
  495.    BRESENHAM_Z( ctx, x1, y1, z1, x2, y2, z2 );
  496.  
  497. #undef BRESENHAM_PLOT
  498. }
  499.  
  500.  
  501. /*
  502.  * Draw a flat-shaded, Z-less, PF_8R8G8B line into an XImage.
  503.  */
  504. static void flat_8R8G8B_z_line( GLcontext *ctx,
  505.                                 GLuint v0, GLuint v1, GLuint pv )
  506. {
  507.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  508.    struct vertex_buffer *VB = ctx->VB;
  509.    GLint x1 = (GLint) VB->Win[v0][0], x2 = (GLint) VB->Win[v1][0];
  510.    GLint y1 = (GLint) VB->Win[v0][1], y2 = (GLint) VB->Win[v1][1];
  511.    GLint z1 = (GLint) (VB->Win[v0][2] + ctx->LineZoffset);
  512.    GLint z2 = (GLint) (VB->Win[v1][2] + ctx->LineZoffset);
  513.    GLuint pixel = PACK_8R8G8B( VB->Color[pv][0], VB->Color[pv][1],
  514.                                VB->Color[pv][2] );
  515.  
  516.    WINCLIP_X(x1,x2);
  517.    WINCLIP_Y(y1,y2);
  518.  
  519. #define BRESENHAM_PLOT(X,Y,Z,ZBUF)        \
  520.     if (Z < *ZBUF) {            \
  521.        GLuint *ptr = PIXELADDR4(X,Y);    \
  522.        *ptr = pixel;            \
  523.        *ZBUF = Z;                \
  524.     }
  525.  
  526.    BRESENHAM_Z( ctx, x1, y1, z1, x2, y2, z2 );
  527.  
  528. #undef BRESENHAM_PLOT
  529. }
  530.  
  531.  
  532. /*
  533.  * Draw a flat-shaded, Z-less, PF_5R6G5B line into an XImage.
  534.  */
  535. static void flat_5R6G5B_z_line( GLcontext *ctx,
  536.                                 GLuint v0, GLuint v1, GLuint pv )
  537. {
  538.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  539.    struct vertex_buffer *VB = ctx->VB;
  540.    GLint x1 = (GLint) VB->Win[v0][0], x2 = (GLint) VB->Win[v1][0];
  541.    GLint y1 = (GLint) VB->Win[v0][1], y2 = (GLint) VB->Win[v1][1];
  542.    GLint z1 = (GLint) (VB->Win[v0][2] + ctx->LineZoffset);
  543.    GLint z2 = (GLint) (VB->Win[v1][2] + ctx->LineZoffset);
  544.    GLuint pixel = PACK_5R6G5B( VB->Color[pv][0], VB->Color[pv][1],
  545.                                VB->Color[pv][2] );
  546.  
  547.    WINCLIP_X(x1,x2);
  548.    WINCLIP_Y(y1,y2);
  549.  
  550. #define BRESENHAM_PLOT(X,Y,Z,ZBUF)        \
  551.     if (Z < *ZBUF) {            \
  552.        GLushort *ptr = PIXELADDR2(X,Y);    \
  553.        *ptr = pixel;            \
  554.        *ZBUF = Z;                \
  555.     }
  556.  
  557.    BRESENHAM_Z( ctx, x1, y1, z1, x2, y2, z2 );
  558.  
  559. #undef BRESENHAM_PLOT
  560. }
  561.  
  562.  
  563. /*
  564.  * Draw a flat-shaded, Z-less, PF_DITHER 8-bit line into an XImage.
  565.  */
  566. static void flat_DITHER8_z_line( GLcontext *ctx,
  567.                                  GLuint v0, GLuint v1, GLuint pv )
  568. {
  569.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  570.    struct vertex_buffer *VB = ctx->VB;
  571.    GLint x1 = (GLint) VB->Win[v0][0], x2 = (GLint) VB->Win[v1][0];
  572.    GLint y1 = (GLint) VB->Win[v0][1], y2 = (GLint) VB->Win[v1][1];
  573.    GLint z1 = (GLint) (VB->Win[v0][2] + ctx->LineZoffset);
  574.    GLint z2 = (GLint) (VB->Win[v1][2] + ctx->LineZoffset);
  575.    GLint r = VB->Color[pv][0], g = VB->Color[pv][1], b = VB->Color[pv][2];
  576.    DITHER_SETUP;
  577.  
  578.    WINCLIP_X(x1,x2);
  579.    WINCLIP_Y(y1,y2);
  580.  
  581. #define BRESENHAM_PLOT(X,Y,Z,ZBUF)        \
  582.     if (Z < *ZBUF) {            \
  583.        GLubyte *ptr = PIXELADDR1(X,Y);    \
  584.        *ptr = DITHER( X, Y, r, g, b);    \
  585.        *ZBUF = Z;                \
  586.     }
  587.  
  588.    BRESENHAM_Z( ctx, x1, y1, z1, x2, y2, z2 );
  589.  
  590. #undef BRESENHAM_PLOT
  591. }
  592.  
  593.  
  594. /*
  595.  * Draw a flat-shaded, Z-less, PF_LOOKUP 8-bit line into an XImage.
  596.  */
  597. static void flat_LOOKUP8_z_line( GLcontext *ctx,
  598.                                  GLuint v0, GLuint v1, GLuint pv )
  599. {
  600.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  601.    struct vertex_buffer *VB = ctx->VB;
  602.    GLint x1 = (GLint) VB->Win[v0][0], x2 = (GLint) VB->Win[v1][0];
  603.    GLint y1 = (GLint) VB->Win[v0][1], y2 = (GLint) VB->Win[v1][1];
  604.    GLint z1 = (GLint) (VB->Win[v0][2] + ctx->LineZoffset);
  605.    GLint z2 = (GLint) (VB->Win[v1][2] + ctx->LineZoffset);
  606.    LOOKUP_SETUP;
  607.    GLubyte pixel = LOOKUP( VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2] );
  608.  
  609.    WINCLIP_X(x1,x2);
  610.    WINCLIP_Y(y1,y2);
  611.  
  612. #define BRESENHAM_PLOT(X,Y,Z,ZBUF)        \
  613.     if (Z < *ZBUF) {            \
  614.        GLubyte *ptr = PIXELADDR1(X,Y);    \
  615.        *ptr = pixel;            \
  616.        *ZBUF = Z;                \
  617.     }
  618.  
  619.    BRESENHAM_Z( ctx, x1, y1, z1, x2, y2, z2 );
  620.  
  621. #undef BRESENHAM_PLOT
  622. }
  623.  
  624.  
  625. /*
  626.  * Draw a flat-shaded, Z-less, PF_HPCR line into an XImage.
  627.  */
  628. static void flat_HPCR_z_line( GLcontext *ctx,
  629.                               GLuint v0, GLuint v1, GLuint pv )
  630. {
  631.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  632.    struct vertex_buffer *VB = ctx->VB;
  633.    GLint x1 = (GLint) VB->Win[v0][0], x2 = (GLint) VB->Win[v1][0];
  634.    GLint y1 = (GLint) VB->Win[v0][1], y2 = (GLint) VB->Win[v1][1];
  635.    GLint z1 = (GLint) (VB->Win[v0][2] + ctx->LineZoffset);
  636.    GLint z2 = (GLint) (VB->Win[v1][2] + ctx->LineZoffset);
  637.    GLint r = VB->Color[pv][0], g = VB->Color[pv][1], b = VB->Color[pv][2];
  638.  
  639.    WINCLIP_X(x1,x2);
  640.    WINCLIP_Y(y1,y2);
  641.  
  642. #define BRESENHAM_PLOT(X,Y,Z,ZBUF)        \
  643.     if (Z < *ZBUF) {            \
  644.        GLubyte *ptr = PIXELADDR1(X,Y);    \
  645.        *ptr = DITHER_HPCR( X, Y, r, g, b);    \
  646.        *ZBUF = Z;                \
  647.     }
  648.  
  649.    BRESENHAM_Z( ctx, x1, y1, z1, x2, y2, z2 );
  650.  
  651. #undef BRESENHAM_PLOT
  652. }
  653.  
  654.  
  655.  
  656. /*
  657.  * Examine ctx->Line attributes and set xmesa->xm_buffer->gc1
  658.  * and xmesa->xm_buffer->gc2 appropriately.
  659.  */
  660. static void setup_x_line_options( GLcontext *ctx )
  661. {
  662.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  663.    int i, state, state0, new_state, len, offs;
  664.    int tbit;
  665.    char *dptr;
  666.    int n_segments = 0;
  667.    char dashes[20];
  668.    int line_width, line_style;
  669.  
  670.    /*** Line Stipple ***/
  671.    if (ctx->Line.StippleFlag) {
  672.       const int pattern = ctx->Line.StipplePattern;
  673.  
  674.       dptr = dashes;
  675.       state0 = state = ((pattern & 1) != 0);
  676.  
  677.       /* Decompose the pattern */
  678.       for (i=1,tbit=2,len=1;i<16;++i,tbit=(tbit<<1))
  679.     {
  680.       new_state = ((tbit & pattern) != 0);
  681.       if (state != new_state)
  682.         {
  683.           *dptr++ = ctx->Line.StippleFactor * len;
  684.           len = 1;
  685.           state = new_state;
  686.         }
  687.       else
  688.         ++len;
  689.     }
  690.       *dptr = ctx->Line.StippleFactor * len;
  691.       n_segments = 1 + (dptr - dashes);
  692.  
  693.       /* ensure an even no. of segments, or X may toggle on/off for consecutive patterns */
  694.       /* if (n_segments & 1)  dashes [n_segments++] = 0;  value of 0 not allowed in dash list */
  695.  
  696.       /* Handle case where line style starts OFF */
  697.       if (state0 == 0)
  698.         offs = dashes[0];
  699.       else
  700.         offs = 0;
  701.  
  702. #if 0
  703. fprintf (stderr, "input pattern: 0x%04x, offset %d, %d segments:", pattern, offs, n_segments);
  704. for (i = 0;  i < n_segments;  i++)
  705. fprintf (stderr, " %d", dashes[i]);
  706. fprintf (stderr, "\n");
  707. #endif
  708.  
  709.       XSetDashes( xmesa->display, xmesa->xm_buffer->gc1, offs, dashes, n_segments );
  710.       XSetDashes( xmesa->display, xmesa->xm_buffer->gc2, offs, dashes, n_segments );
  711.  
  712.       line_style = LineOnOffDash;
  713.    }
  714.    else {
  715.       line_style = LineSolid;
  716.    }
  717.  
  718.    /*** Line Width ***/
  719.    line_width = (int) (ctx->Line.Width+0.5F);
  720.    if (line_width < 2) {
  721.       /* Use fast lines when possible */
  722.       line_width = 0;
  723.    }
  724.  
  725.    /*** Set GC attributes ***/
  726.    XSetLineAttributes( xmesa->display, xmesa->xm_buffer->gc1,
  727.                        line_width, line_style, CapButt, JoinBevel);
  728.    XSetLineAttributes( xmesa->display, xmesa->xm_buffer->gc2,
  729.                        line_width, line_style, CapButt, JoinBevel);
  730.    XSetFillStyle( xmesa->display, xmesa->xm_buffer->gc1, FillSolid );
  731.    XSetFillStyle( xmesa->display, xmesa->xm_buffer->gc2, FillSolid );
  732. }
  733.  
  734.  
  735.  
  736. /*
  737.  * Analyze context state to see if we can provide a fast line drawing
  738.  * function, like those in lines.c.  Otherwise, return NULL.
  739.  */
  740. line_func xmesa_get_line_func( GLcontext *ctx )
  741. {
  742.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  743.    int depth = xmesa->xm_visual->visinfo->depth;
  744.  
  745.    if (ctx->Line.SmoothFlag)              return NULL;
  746.    if (ctx->Texture.Enabled)              return NULL;
  747.    if (ctx->Light.ShadeModel!=GL_FLAT)    return NULL;
  748.  
  749.    if (xmesa->xm_buffer->buffer==XIMAGE
  750.        && ctx->RasterMask==DEPTH_BIT
  751.        && ctx->Depth.Func==GL_LESS
  752.        && ctx->Depth.Mask==GL_TRUE
  753.        && ctx->Line.Width==1.0F
  754.        && ctx->Line.StippleFlag==GL_FALSE) {
  755.       switch (xmesa->pixelformat) {
  756.          case PF_TRUECOLOR:
  757.             return flat_TRUECOLOR_z_line;
  758.          case PF_8A8B8G8R:
  759.             return flat_8A8B8G8R_z_line;
  760.          case PF_8R8G8B:
  761.             return flat_8R8G8B_z_line;
  762.          case PF_5R6G5B:
  763.             return flat_5R6G5B_z_line;
  764.          case PF_DITHER:
  765.             return (depth==8) ? flat_DITHER8_z_line : NULL;
  766.          case PF_LOOKUP:
  767.             return (depth==8) ? flat_LOOKUP8_z_line : NULL;
  768.          case PF_HPCR:
  769.             return flat_HPCR_z_line;
  770.          default:
  771.             return NULL;
  772.       }
  773.    }
  774.    if (xmesa->xm_buffer->buffer==XIMAGE
  775.        && ctx->RasterMask==0
  776.        && ctx->Line.Width==1.0F
  777.        && ctx->Line.StippleFlag==GL_FALSE) {
  778.       switch (xmesa->pixelformat) {
  779.          case PF_TRUECOLOR:
  780.             return flat_TRUECOLOR_line;
  781.          case PF_8A8B8G8R:
  782.             return flat_8A8B8G8R_line;
  783.          case PF_8R8G8B:
  784.             return flat_8R8G8B_line;
  785.          case PF_5R6G5B:
  786.             return flat_5R6G5B_line;
  787.          case PF_DITHER:
  788.             return (depth==8) ? flat_DITHER8_line : NULL;
  789.          case PF_LOOKUP:
  790.             return (depth==8) ? flat_LOOKUP8_line : NULL;
  791.          case PF_HPCR:
  792.             return flat_HPCR_line;
  793.      default:
  794.         return NULL;
  795.       }
  796.    }
  797.    if (xmesa->xm_buffer->buffer!=XIMAGE && ctx->RasterMask==0) {
  798.       setup_x_line_options( ctx );
  799.       return flat_pixmap_line;
  800.    }
  801.    return NULL;
  802. }
  803.  
  804.  
  805.  
  806.  
  807. /**********************************************************************/
  808. /***                   Triangle rendering                            ***/
  809. /**********************************************************************/
  810.  
  811. /*
  812.  * Render a triangle into a pixmap, any pixel format, flat shaded and
  813.  * no raster ops.
  814.  */
  815. void flat_pixmap_triangle( GLcontext *ctx,
  816.                         GLuint v0, GLuint v1, GLuint v2, GLuint pv )
  817. {
  818.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  819.    struct vertex_buffer *VB = ctx->VB;
  820.    XPoint p[3];
  821.    GC gc;
  822.    if (VB->MonoColor) {
  823.       gc = xmesa->xm_buffer->gc1;  /* use current color */
  824.    }
  825.    else {
  826.       unsigned long pixel;
  827.       if (xmesa->xm_visual->gl_visual->RGBAflag) {
  828.          pixel = xmesa_color_to_pixel( xmesa,
  829.                                        VB->Color[pv][0], VB->Color[pv][1],
  830.                                        VB->Color[pv][2], VB->Color[pv][3] );
  831.       }
  832.       else {
  833.          pixel = VB->Index[pv];
  834.       }
  835.       gc = xmesa->xm_buffer->gc2;
  836.       XSetForeground( xmesa->display, gc, pixel );
  837.    }
  838.    p[0].x =       (GLint) (VB->Win[v0][0] + 0.5f);
  839.    p[0].y = FLIP( (GLint) (VB->Win[v0][1] - 0.5f) );
  840.    p[1].x =       (GLint) (VB->Win[v1][0] + 0.5f);
  841.    p[1].y = FLIP( (GLint) (VB->Win[v1][1] - 0.5f) );
  842.    p[2].x =       (GLint) (VB->Win[v2][0] + 0.5f);
  843.    p[2].y = FLIP( (GLint) (VB->Win[v2][1] - 0.5f) );
  844.    XFillPolygon( xmesa->display, xmesa->xm_buffer->buffer, gc,
  845.          p, 3, Convex, CoordModeOrigin );
  846. }
  847.  
  848.  
  849.  
  850. /*
  851.  * XImage, smooth, depth-buffered, PF_TRUECOLOR triangle.
  852.  */
  853. static void smooth_TRUECOLOR_z_triangle( GLcontext *ctx,
  854.                                          GLuint v0, GLuint v1, GLuint v2,
  855.                                          GLuint pv )
  856. {
  857.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  858.    XImage *img = xmesa->xm_buffer->backimage;
  859. #define INTERP_Z 1
  860. #define INTERP_RGB 1
  861. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  862. {                                    \
  863.    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;            \
  864.    for (i=0;i<len;i++,xx++) {                        \
  865.       GLdepth z = FixedToDepth(ffz);                    \
  866.       if (z < zRow[i]) {                        \
  867.          unsigned long p = PACK_RGB( FixedToInt(ffr), FixedToInt(ffg),    \
  868.                      FixedToInt(ffb) );        \
  869.          XPutPixel( img, xx, yy, p );                    \
  870.          zRow[i] = z;                            \
  871.       }                                    \
  872.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  873.       ffz += fdzdx;                            \
  874.    }                                    \
  875. }
  876. #include "tritemp.h"
  877. }
  878.  
  879.  
  880.  
  881. /*
  882.  * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
  883.  */
  884. static void smooth_8A8B8G8R_z_triangle( GLcontext *ctx,
  885.                                          GLuint v0, GLuint v1, GLuint v2,
  886.                                          GLuint pv )
  887. {
  888.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  889. #define INTERP_Z 1
  890. #define INTERP_RGB 1
  891. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  892. #define PIXEL_TYPE GLuint
  893. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  894. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  895. {                                    \
  896.    GLint i, len = RIGHT-LEFT;                        \
  897.    for (i=0;i<len;i++) {                        \
  898.       GLdepth z = FixedToDepth(ffz);                    \
  899.       if (z < zRow[i]) {                        \
  900.          pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg),    \
  901.                  FixedToInt(ffb) );            \
  902.          zRow[i] = z;                            \
  903.       }                                    \
  904.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  905.       ffz += fdzdx;                            \
  906.    }                                    \
  907. }
  908. #include "tritemp.h"
  909. }
  910.  
  911.  
  912. /*
  913.  * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
  914.  */
  915. static void smooth_8R8G8B_z_triangle( GLcontext *ctx,
  916.                                          GLuint v0, GLuint v1, GLuint v2,
  917.                                          GLuint pv )
  918. {
  919.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  920. #define INTERP_Z 1
  921. #define INTERP_RGB 1
  922. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  923. #define PIXEL_TYPE GLuint
  924. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  925. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  926. {                                    \
  927.    GLint i, len = RIGHT-LEFT;                        \
  928.    for (i=0;i<len;i++) {                        \
  929.       GLdepth z = FixedToDepth(ffz);                    \
  930.       if (z < zRow[i]) {                        \
  931.          pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg),    \
  932.                  FixedToInt(ffb) );            \
  933.          zRow[i] = z;                            \
  934.       }                                    \
  935.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  936.       ffz += fdzdx;                            \
  937.    }                                    \
  938. }
  939. #include "tritemp.h"
  940. }
  941.  
  942.  
  943.  
  944. /*
  945.  * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
  946.  */
  947. static void smooth_5R6G5B_z_triangle( GLcontext *ctx,
  948.                                          GLuint v0, GLuint v1, GLuint v2,
  949.                                          GLuint pv )
  950. {
  951.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  952. #define INTERP_Z 1
  953. #define INTERP_RGB 1
  954. #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
  955. #define PIXEL_TYPE GLushort
  956. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  957. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  958. {                                    \
  959.    GLint i, len = RIGHT-LEFT;                        \
  960.    for (i=0;i<len;i++) {                        \
  961.       GLdepth z = FixedToDepth(ffz);                    \
  962.       if (z < zRow[i]) {                        \
  963.          pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg),    \
  964.                  FixedToInt(ffb) );            \
  965.          zRow[i] = z;                            \
  966.       }                                    \
  967.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  968.       ffz += fdzdx;                            \
  969.    }                                    \
  970. }
  971. #include "tritemp.h"
  972. }
  973.  
  974.  
  975. /*
  976.  * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
  977.  */
  978. static void smooth_DITHER8_z_triangle( GLcontext *ctx,
  979.                                        GLuint v0, GLuint v1, GLuint v2,
  980.                                        GLuint pv )
  981. {
  982.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  983. #define INTERP_Z 1
  984. #define INTERP_RGB 1
  985. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  986. #define PIXEL_TYPE GLubyte
  987. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  988. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  989. {                                    \
  990.    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;            \
  991.    XDITHER_SETUP(yy);                            \
  992.    for (i=0;i<len;i++,xx++) {                        \
  993.       GLdepth z = FixedToDepth(ffz);                    \
  994.       if (z < zRow[i]) {                        \
  995.          pRow[i] = XDITHER( xx, FixedToInt(ffr), FixedToInt(ffg),    \
  996.                 FixedToInt(ffb) );            \
  997.          zRow[i] = z;                            \
  998.       }                                    \
  999.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  1000.       ffz += fdzdx;                            \
  1001.    }                                    \
  1002. }
  1003. #include "tritemp.h"
  1004. }
  1005.  
  1006.  
  1007.  
  1008. /*
  1009.  * XImage, smooth, depth-buffered, PF_DITHER triangle.
  1010.  */
  1011. static void smooth_DITHER_z_triangle( GLcontext *ctx,
  1012.                                        GLuint v0, GLuint v1, GLuint v2,
  1013.                                        GLuint pv )
  1014. {
  1015.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1016.    XImage *img = xmesa->xm_buffer->backimage;
  1017. #define INTERP_Z 1
  1018. #define INTERP_RGB 1
  1019. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  1020. #define PIXEL_TYPE GLubyte
  1021. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1022. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1023. {                                    \
  1024.    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;            \
  1025.    XDITHER_SETUP(yy);                            \
  1026.    for (i=0;i<len;i++,xx++) {                        \
  1027.       GLdepth z = FixedToDepth(ffz);                    \
  1028.       if (z < zRow[i]) {                        \
  1029.      unsigned long p = XDITHER( xx, FixedToInt(ffr),        \
  1030.                  FixedToInt(ffg), FixedToInt(ffb) );    \
  1031.      XPutPixel( img, xx, yy, p );                    \
  1032.          zRow[i] = z;                            \
  1033.       }                                    \
  1034.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  1035.       ffz += fdzdx;                            \
  1036.    }                                    \
  1037. }
  1038. #include "tritemp.h"
  1039. }
  1040.  
  1041.  
  1042. /*
  1043.  * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
  1044.  */
  1045. static void smooth_LOOKUP8_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1046.                                        GLuint v2, GLuint pv )
  1047. {
  1048.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1049. #define INTERP_Z 1
  1050. #define INTERP_RGB 1
  1051. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  1052. #define PIXEL_TYPE GLubyte
  1053. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1054. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1055. {                                    \
  1056.    GLint i, len = RIGHT-LEFT;                        \
  1057.    LOOKUP_SETUP;                            \
  1058.    for (i=0;i<len;i++) {                        \
  1059.       GLdepth z = FixedToDepth(ffz);                    \
  1060.       if (z < zRow[i]) {                        \
  1061.          pRow[i] = LOOKUP( FixedToInt(ffr), FixedToInt(ffg),        \
  1062.                  FixedToInt(ffb) );            \
  1063.          zRow[i] = z;                            \
  1064.       }                                    \
  1065.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  1066.       ffz += fdzdx;                            \
  1067.    }                                    \
  1068. }
  1069. #include "tritemp.h"
  1070. }
  1071.  
  1072.  
  1073.  
  1074. /*
  1075.  * XImage, smooth, depth-buffered, 8-bit PF_HPCR triangle.
  1076.  */
  1077. static void smooth_HPCR_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1078.                                     GLuint v2, GLuint pv )
  1079. {
  1080.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1081. #define INTERP_Z 1
  1082. #define INTERP_RGB 1
  1083. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  1084. #define PIXEL_TYPE GLubyte
  1085. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1086. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1087. {                                    \
  1088.    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;            \
  1089.    for (i=0;i<len;i++,xx++) {                        \
  1090.       GLdepth z = FixedToDepth(ffz);                    \
  1091.       if (z < zRow[i]) {                        \
  1092.          pRow[i] = DITHER_HPCR( xx, yy, FixedToInt(ffr),        \
  1093.                  FixedToInt(ffg), FixedToInt(ffb) );    \
  1094.          zRow[i] = z;                            \
  1095.       }                                    \
  1096.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  1097.       ffz += fdzdx;                            \
  1098.    }                                    \
  1099. }
  1100. #include "tritemp.h"
  1101. }
  1102.  
  1103.  
  1104.  
  1105. /*
  1106.  * XImage, flat, depth-buffered, PF_TRUECOLOR triangle.
  1107.  */
  1108. static void flat_TRUECOLOR_z_triangle( GLcontext *ctx,
  1109.                                    GLuint v0, GLuint v1, GLuint v2,
  1110.                                        GLuint pv )
  1111. {
  1112.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1113.    XImage *img = xmesa->xm_buffer->backimage;
  1114. #define INTERP_Z 1
  1115. #define SETUP_CODE                    \
  1116.    unsigned long pixel = PACK_RGB( VB->Color[pv][0],    \
  1117.          VB->Color[pv][1], VB->Color[pv][2] );
  1118.  
  1119. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1120. {                                    \
  1121.    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;            \
  1122.    for (i=0;i<len;i++,xx++) {                        \
  1123.       GLdepth z = FixedToDepth(ffz);                    \
  1124.       if (z < zRow[i]) {                        \
  1125.          XPutPixel( img, xx, yy, pixel );                \
  1126.          zRow[i] = z;                            \
  1127.       }                                    \
  1128.       ffz += fdzdx;                            \
  1129.    }                                    \
  1130. }
  1131. #include "tritemp.h"
  1132. }
  1133.  
  1134.  
  1135. /*
  1136.  * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
  1137.  */
  1138. static void flat_8A8B8G8R_z_triangle( GLcontext *ctx, GLuint v0,
  1139.                                   GLuint v1, GLuint v2, GLuint pv )
  1140. {
  1141.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1142. #define INTERP_Z 1
  1143. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  1144. #define PIXEL_TYPE GLuint
  1145. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1146. #define SETUP_CODE                    \
  1147.    unsigned long p = PACK_8B8G8R( VB->Color[pv][0],    \
  1148.          VB->Color[pv][1], VB->Color[pv][2] );
  1149. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1150. {                                    \
  1151.    GLint i, len = RIGHT-LEFT;                        \
  1152.    for (i=0;i<len;i++) {                        \
  1153.       GLdepth z = FixedToDepth(ffz);                    \
  1154.       if (z < zRow[i]) {                        \
  1155.      pRow[i] = p;                            \
  1156.          zRow[i] = z;                            \
  1157.       }                                    \
  1158.       ffz += fdzdx;                            \
  1159.    }                                    \
  1160. }
  1161. #include "tritemp.h"
  1162. }
  1163.  
  1164.  
  1165. /*
  1166.  * XImage, flat, depth-buffered, PF_8R8G8B triangle.
  1167.  */
  1168. static void flat_8R8G8B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1169.                                     GLuint v2, GLuint pv )
  1170. {
  1171.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1172. #define INTERP_Z 1
  1173. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  1174. #define PIXEL_TYPE GLuint
  1175. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1176. #define SETUP_CODE                    \
  1177.    unsigned long p = PACK_8R8G8B( VB->Color[pv][0],    \
  1178.          VB->Color[pv][1], VB->Color[pv][2] );
  1179. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  1180. {                            \
  1181.    GLint i, len = RIGHT-LEFT;                \
  1182.    for (i=0;i<len;i++) {                \
  1183.       GLdepth z = FixedToDepth(ffz);            \
  1184.       if (z < zRow[i]) {                \
  1185.      pRow[i] = p;                    \
  1186.          zRow[i] = z;                    \
  1187.       }                            \
  1188.       ffz += fdzdx;                    \
  1189.    }                            \
  1190. }
  1191. #include "tritemp.h"
  1192. }
  1193.  
  1194.  
  1195. /*
  1196.  * XImage, flat, depth-buffered, PF_5R6G5B triangle.
  1197.  */
  1198. static void flat_5R6G5B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1199.                                     GLuint v2, GLuint pv )
  1200. {
  1201.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1202. #define INTERP_Z 1
  1203. #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
  1204. #define PIXEL_TYPE GLushort
  1205. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1206. #define SETUP_CODE                    \
  1207.    unsigned long p = PACK_5R6G5B( VB->Color[pv][0],    \
  1208.          VB->Color[pv][1], VB->Color[pv][2] );
  1209. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  1210. {                            \
  1211.    GLint i, len = RIGHT-LEFT;                \
  1212.    for (i=0;i<len;i++) {                \
  1213.       GLdepth z = FixedToDepth(ffz);            \
  1214.       if (z < zRow[i]) {                \
  1215.      pRow[i] = p;                    \
  1216.          zRow[i] = z;                    \
  1217.       }                            \
  1218.       ffz += fdzdx;                    \
  1219.    }                            \
  1220. }
  1221. #include "tritemp.h"
  1222. }
  1223.  
  1224.  
  1225. /*
  1226.  * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
  1227.  */
  1228. static void flat_DITHER8_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1229.                                      GLuint v2, GLuint pv )
  1230. {
  1231.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1232. #define INTERP_Z 1
  1233. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  1234. #define PIXEL_TYPE GLubyte
  1235. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1236. #define SETUP_CODE    \
  1237.    FLAT_DITHER_SETUP( VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2] );
  1238.  
  1239. #define INNER_LOOP( LEFT, RIGHT, Y )                \
  1240. {                                \
  1241.    GLint i, xx = LEFT, len = RIGHT-LEFT;            \
  1242.    FLAT_DITHER_ROW_SETUP(FLIP(Y));                \
  1243.    for (i=0;i<len;i++,xx++) {                    \
  1244.       GLdepth z = FixedToDepth(ffz);                \
  1245.       if (z < zRow[i]) {                    \
  1246.      pRow[i] = FLAT_DITHER(xx);                \
  1247.          zRow[i] = z;                        \
  1248.       }                                \
  1249.       ffz += fdzdx;                        \
  1250.    }                                \
  1251. }
  1252. #include "tritemp.h"
  1253. }
  1254.  
  1255.  
  1256. /*
  1257.  * XImage, flat, depth-buffered, PF_DITHER triangle.
  1258.  */
  1259. static void flat_DITHER_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1260.                                     GLuint v2, GLuint pv )
  1261. {
  1262.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1263.    XImage *img = xmesa->xm_buffer->backimage;
  1264. #define INTERP_Z 1
  1265. #define SETUP_CODE    \
  1266.    FLAT_DITHER_SETUP( VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2] );
  1267.  
  1268. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1269. {                                    \
  1270.    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;            \
  1271.    FLAT_DITHER_ROW_SETUP(yy);                        \
  1272.    for (i=0;i<len;i++,xx++) {                        \
  1273.       GLdepth z = FixedToDepth(ffz);                    \
  1274.       if (z < zRow[i]) {                        \
  1275.          unsigned long p = FLAT_DITHER(xx);                \
  1276.      XPutPixel( img, xx, yy, p );                    \
  1277.          zRow[i] = z;                            \
  1278.       }                                    \
  1279.       ffz += fdzdx;                            \
  1280.    }                                    \
  1281. }
  1282. #include "tritemp.h"
  1283. }
  1284.  
  1285.  
  1286. /*
  1287.  * XImage, flat, depth-buffered, 8-bit PF_HPCR triangle.
  1288.  */
  1289. static void flat_HPCR_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1290.                                   GLuint v2, GLuint pv )
  1291. {
  1292.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1293. #define INTERP_Z 1
  1294. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  1295. #define PIXEL_TYPE GLubyte
  1296. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1297. #define SETUP_CODE                \
  1298.    GLubyte r = VB->Color[pv][0];        \
  1299.    GLubyte g = VB->Color[pv][1];        \
  1300.    GLubyte b = VB->Color[pv][2];
  1301. #define INNER_LOOP( LEFT, RIGHT, Y )                \
  1302. {                                \
  1303.    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;        \
  1304.    for (i=0;i<len;i++,xx++) {                    \
  1305.       GLdepth z = FixedToDepth(ffz);                \
  1306.       if (z < zRow[i]) {                    \
  1307.      pRow[i] = DITHER_HPCR( xx, yy, r, g, b );        \
  1308.          zRow[i] = z;                        \
  1309.       }                                \
  1310.       ffz += fdzdx;                        \
  1311.    }                                \
  1312. }
  1313. #include "tritemp.h"
  1314. }
  1315.  
  1316.  
  1317.  
  1318. /*
  1319.  * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
  1320.  */
  1321. static void flat_LOOKUP8_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1322.                                  GLuint v2, GLuint pv )
  1323. {
  1324.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1325. #define INTERP_Z 1
  1326. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  1327. #define PIXEL_TYPE GLubyte
  1328. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1329. #define SETUP_CODE                \
  1330.    LOOKUP_SETUP;                \
  1331.    GLubyte r = VB->Color[pv][0];        \
  1332.    GLubyte g = VB->Color[pv][1];        \
  1333.    GLubyte b = VB->Color[pv][2];        \
  1334.    GLubyte p = LOOKUP(r,g,b);
  1335. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  1336. {                            \
  1337.    GLint i, len = RIGHT-LEFT;                \
  1338.    for (i=0;i<len;i++) {                \
  1339.       GLdepth z = FixedToDepth(ffz);            \
  1340.       if (z < zRow[i]) {                \
  1341.      pRow[i] = p;                    \
  1342.          zRow[i] = z;                    \
  1343.       }                            \
  1344.       ffz += fdzdx;                    \
  1345.    }                            \
  1346. }
  1347. #include "tritemp.h"
  1348. }
  1349.  
  1350.  
  1351.  
  1352. /*
  1353.  * XImage, smooth, NON-depth-buffered, PF_TRUECOLOR triangle.
  1354.  */
  1355. static void smooth_TRUECOLOR_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1356.                                        GLuint v2, GLuint pv )
  1357. {
  1358.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1359.    XImage *img = xmesa->xm_buffer->backimage;
  1360. #define INTERP_RGB 1
  1361. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1362. {                                    \
  1363.    GLint xx, yy = FLIP(Y);                        \
  1364.    for (xx=LEFT;xx<RIGHT;xx++) {                    \
  1365.       unsigned long p = PACK_RGB( FixedToInt(ffr), FixedToInt(ffg),    \
  1366.                     FixedToInt(ffb) );        \
  1367.       XPutPixel( img, xx, yy, p );                    \
  1368.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  1369.    }                                    \
  1370. }
  1371. #include "tritemp.h"
  1372. }
  1373.  
  1374.  
  1375. /*
  1376.  * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
  1377.  */
  1378. static void smooth_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1379.                       GLuint v2, GLuint pv )
  1380. {
  1381.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1382. #define INTERP_RGB 1
  1383. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  1384. #define PIXEL_TYPE GLuint
  1385. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1386. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1387. {                                    \
  1388.    GLint xx;                                \
  1389.    PIXEL_TYPE *pixel = pRow;                        \
  1390.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                \
  1391.       *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg),        \
  1392.                 FixedToInt(ffb) );            \
  1393.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  1394.    }                                    \
  1395. }
  1396. #include "tritemp.h"
  1397. }
  1398.  
  1399.  
  1400. /*
  1401.  * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
  1402.  */
  1403. static void smooth_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1404.                                     GLuint v2, GLuint pv )
  1405. {
  1406.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1407. #define INTERP_RGB 1
  1408. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  1409. #define PIXEL_TYPE GLuint
  1410. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1411. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1412. {                                    \
  1413.    GLint xx;                                \
  1414.    PIXEL_TYPE *pixel = pRow;                        \
  1415.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                \
  1416.       *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg),        \
  1417.                 FixedToInt(ffb) );            \
  1418.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  1419.    }                                    \
  1420. }
  1421. #include "tritemp.h"
  1422. }
  1423.  
  1424.  
  1425. /*
  1426.  * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
  1427.  */
  1428. static void smooth_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1429.                     GLuint v2, GLuint pv )
  1430. {
  1431.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1432. #define INTERP_RGB 1
  1433. #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
  1434. #define PIXEL_TYPE GLushort
  1435. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1436. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1437. {                                    \
  1438.    GLint xx;                                \
  1439.    PIXEL_TYPE *pixel = pRow;                        \
  1440.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                \
  1441.       *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg),        \
  1442.                 FixedToInt(ffb) );            \
  1443.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  1444.    }                                    \
  1445. }
  1446. #include "tritemp.h"
  1447. }
  1448.  
  1449.  
  1450. /*
  1451.  * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
  1452.  */
  1453. static void smooth_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1454.                      GLuint v2, GLuint pv )
  1455. {
  1456.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1457. #define INTERP_RGB 1
  1458. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  1459. #define PIXEL_TYPE GLubyte
  1460. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1461. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1462. {                                    \
  1463.    GLint xx, yy = FLIP(Y);                        \
  1464.    PIXEL_TYPE *pixel = pRow;                        \
  1465.    XDITHER_SETUP(yy);                            \
  1466.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                \
  1467.       *pixel = XDITHER( xx, FixedToInt(ffr), FixedToInt(ffg),        \
  1468.                 FixedToInt(ffb) );            \
  1469.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  1470.    }                                    \
  1471. }
  1472. #include "tritemp.h"
  1473. }
  1474.  
  1475.  
  1476. /*
  1477.  * XImage, smooth, NON-depth-buffered, PF_DITHER triangle.
  1478.  */
  1479. static void smooth_DITHER_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1480.                                     GLuint v2, GLuint pv )
  1481. {
  1482.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1483.    XImage *img = xmesa->xm_buffer->backimage;
  1484. #define INTERP_RGB 1
  1485. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1486. {                                    \
  1487.    GLint xx, yy = FLIP(Y);                        \
  1488.    XDITHER_SETUP(yy);                            \
  1489.    for (xx=LEFT;xx<RIGHT;xx++) {                    \
  1490.       unsigned long p = XDITHER( xx, FixedToInt(ffr),            \
  1491.                 FixedToInt(ffg), FixedToInt(ffb) );    \
  1492.       XPutPixel( img, xx, yy, p );                    \
  1493.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  1494.    }                                    \
  1495. }
  1496. #include "tritemp.h"
  1497. }
  1498.  
  1499.  
  1500. /*
  1501.  * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
  1502.  */
  1503. static void smooth_LOOKUP8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1504.                                      GLuint v2, GLuint pv )
  1505. {
  1506.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1507. #define INTERP_RGB 1
  1508. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  1509. #define PIXEL_TYPE GLubyte
  1510. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1511. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1512. {                                    \
  1513.    GLint xx;                                \
  1514.    PIXEL_TYPE *pixel = pRow;                        \
  1515.    LOOKUP_SETUP;                            \
  1516.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                \
  1517.       *pixel = LOOKUP( FixedToInt(ffr), FixedToInt(ffg),        \
  1518.             FixedToInt(ffb) );                \
  1519.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  1520.    }                                    \
  1521. }
  1522. #include "tritemp.h"
  1523. }
  1524.  
  1525.  
  1526.  
  1527. /*
  1528.  * XImage, smooth, NON-depth-buffered, 8-bit PF_HPCR triangle.
  1529.  */
  1530. static void smooth_HPCR_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1531.                                   GLuint v2, GLuint pv )
  1532. {
  1533.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1534. #define INTERP_RGB 1
  1535. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  1536. #define PIXEL_TYPE GLubyte
  1537. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1538. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1539. {                                    \
  1540.    GLint xx, yy = FLIP(Y);                        \
  1541.    PIXEL_TYPE *pixel = pRow;                        \
  1542.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                \
  1543.       *pixel = DITHER_HPCR( xx, yy, FixedToInt(ffr),            \
  1544.                 FixedToInt(ffg), FixedToInt(ffb) );    \
  1545.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  1546.    }                                    \
  1547. }
  1548. #include "tritemp.h"
  1549. }
  1550.  
  1551.  
  1552. /*
  1553.  * XImage, flat, NON-depth-buffered, PF_TRUECOLOR triangle.
  1554.  */
  1555. static void flat_TRUECOLOR_triangle( GLcontext *ctx, GLuint v0,
  1556.                                      GLuint v1, GLuint v2, GLuint pv )
  1557. {
  1558.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1559.    XImage *img = xmesa->xm_buffer->backimage;
  1560. #define SETUP_CODE                    \
  1561.    unsigned long pixel = PACK_RGB( VB->Color[pv][0],    \
  1562.          VB->Color[pv][1], VB->Color[pv][2] );
  1563. #define INNER_LOOP( LEFT, RIGHT, Y )                \
  1564. {                                \
  1565.    GLint xx, yy = FLIP(Y);                    \
  1566.    for (xx=LEFT;xx<RIGHT;xx++) {                \
  1567.       XPutPixel( img, xx, yy, pixel );                \
  1568.    }                                \
  1569. }
  1570. #include "tritemp.h"
  1571. }
  1572.  
  1573.  
  1574. /*
  1575.  * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
  1576.  */
  1577. static void flat_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0,
  1578.                                 GLuint v1, GLuint v2, GLuint pv )
  1579. {
  1580.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1581. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  1582. #define PIXEL_TYPE GLuint
  1583. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1584. #define SETUP_CODE                    \
  1585.    unsigned long p = PACK_8B8G8R( VB->Color[pv][0],    \
  1586.          VB->Color[pv][1], VB->Color[pv][2] );
  1587. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  1588. {                            \
  1589.    GLint xx;                        \
  1590.    PIXEL_TYPE *pixel = pRow;                \
  1591.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {        \
  1592.       *pixel = p;                    \
  1593.    }                            \
  1594. }
  1595. #include "tritemp.h"
  1596. }
  1597.  
  1598.  
  1599. /*
  1600.  * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
  1601.  */
  1602. static void flat_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1603.                                   GLuint v2, GLuint pv )
  1604. {
  1605.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1606. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  1607. #define PIXEL_TYPE GLuint
  1608. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1609. #define SETUP_CODE                    \
  1610.    unsigned long p = PACK_8R8G8B( VB->Color[pv][0],    \
  1611.          VB->Color[pv][1], VB->Color[pv][2] );
  1612. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  1613. {                            \
  1614.    GLint xx;                        \
  1615.    PIXEL_TYPE *pixel = pRow;                \
  1616.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {        \
  1617.       *pixel = p;                    \
  1618.    }                            \
  1619. }
  1620. #include "tritemp.h"
  1621. }
  1622.  
  1623.  
  1624. /*
  1625.  * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
  1626.  */
  1627. static void flat_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1628.                                   GLuint v2, GLuint pv )
  1629. {
  1630.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1631. #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
  1632. #define PIXEL_TYPE GLushort
  1633. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1634. #define SETUP_CODE                    \
  1635.    unsigned long p = PACK_5R6G5B( VB->Color[pv][0],    \
  1636.          VB->Color[pv][1], VB->Color[pv][2] );
  1637. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  1638. {                            \
  1639.    GLint xx;                        \
  1640.    PIXEL_TYPE *pixel = pRow;                \
  1641.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {        \
  1642.       *pixel = p;                    \
  1643.    }                            \
  1644. }
  1645. #include "tritemp.h"
  1646. }
  1647.  
  1648.  
  1649. /*
  1650.  * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
  1651.  */
  1652. static void flat_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1653.                                    GLuint v2, GLuint pv )
  1654. {
  1655.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1656. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  1657. #define PIXEL_TYPE GLubyte
  1658. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1659. #define SETUP_CODE    \
  1660.    FLAT_DITHER_SETUP( VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2] );
  1661.  
  1662. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  1663. {                            \
  1664.    GLint xx;                        \
  1665.    PIXEL_TYPE *pixel = pRow;                \
  1666.    FLAT_DITHER_ROW_SETUP(FLIP(Y));            \
  1667.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {        \
  1668.       *pixel = FLAT_DITHER(xx);                \
  1669.    }                            \
  1670. }
  1671. #include "tritemp.h"
  1672. }
  1673.  
  1674.  
  1675. /*
  1676.  * XImage, flat, NON-depth-buffered, PF_DITHER triangle.
  1677.  */
  1678. static void flat_DITHER_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1679.                                   GLuint v2, GLuint pv )
  1680. {
  1681.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1682.    XImage *img = xmesa->xm_buffer->backimage;
  1683. #define SETUP_CODE    \
  1684.    FLAT_DITHER_SETUP( VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2] );
  1685.  
  1686. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  1687. {                            \
  1688.    GLint xx, yy = FLIP(Y);                \
  1689.    FLAT_DITHER_ROW_SETUP(yy);                \
  1690.    for (xx=LEFT;xx<RIGHT;xx++) {            \
  1691.       unsigned long p = FLAT_DITHER(xx);        \
  1692.       XPutPixel( img, xx, yy, p );            \
  1693.    }                            \
  1694. }
  1695. #include "tritemp.h"
  1696. }
  1697.  
  1698.  
  1699. /*
  1700.  * XImage, flat, NON-depth-buffered, 8-bit PF_HPCR triangle.
  1701.  */
  1702. static void flat_HPCR_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1703.                                 GLuint v2, GLuint pv )
  1704. {
  1705.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1706. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  1707. #define PIXEL_TYPE GLubyte
  1708. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1709. #define SETUP_CODE                \
  1710.    GLubyte r = VB->Color[pv][0];        \
  1711.    GLubyte g = VB->Color[pv][1];        \
  1712.    GLubyte b = VB->Color[pv][2];
  1713. #define INNER_LOOP( LEFT, RIGHT, Y )        \
  1714. {                        \
  1715.    GLint xx, yy = FLIP(Y);            \
  1716.    PIXEL_TYPE *pixel = pRow;            \
  1717.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {    \
  1718.       *pixel = DITHER_HPCR( xx, yy, r, g, b );    \
  1719.    }                        \
  1720. }
  1721. #include "tritemp.h"
  1722. }
  1723.  
  1724.  
  1725. /*
  1726.  * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
  1727.  */
  1728. static void flat_LOOKUP8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1729.                                GLuint v2, GLuint pv )
  1730. {
  1731.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1732. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  1733. #define PIXEL_TYPE GLubyte
  1734. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  1735. #define SETUP_CODE                \
  1736.    LOOKUP_SETUP;                \
  1737.    GLubyte r = VB->Color[pv][0];        \
  1738.    GLubyte g = VB->Color[pv][1];        \
  1739.    GLubyte b = VB->Color[pv][2];        \
  1740.    GLubyte p = LOOKUP(r,g,b);
  1741. #define INNER_LOOP( LEFT, RIGHT, Y )        \
  1742. {                        \
  1743.    GLint xx;                    \
  1744.    PIXEL_TYPE *pixel = pRow;            \
  1745.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {    \
  1746.       *pixel = p;                \
  1747.    }                        \
  1748. }
  1749. #include "tritemp.h"
  1750. }
  1751.  
  1752.  
  1753.  
  1754.  
  1755. /*
  1756.  * This function is called if we're about to render triangles into an
  1757.  * X window/pixmap.  It sets the polygon stipple pattern if enabled.
  1758.  */
  1759. static void setup_x_polygon_options( GLcontext *ctx )
  1760. {
  1761.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1762.    int fill_type;
  1763.  
  1764.    if (ctx->Polygon.StippleFlag) {
  1765.       /*
  1766.        * Allocate polygon stippling stuff once for this context.
  1767.        */
  1768.       if (xmesa->xm_buffer->stipple_pixmap == 0) {
  1769.          XGCValues values;
  1770.          XMesaBuffer b = xmesa->xm_buffer;
  1771.          b->stipple_pixmap = XCreatePixmap( xmesa->display,
  1772.                                             b->buffer, 32, 32, 1 );
  1773.          values.function = GXcopy;
  1774.          values.foreground = 1;
  1775.          values.background = 0;
  1776.          b->stipple_gc = XCreateGC( xmesa->display, b->stipple_pixmap,
  1777.                                     (GCFunction|GCForeground|GCBackground),
  1778.                                     &values );
  1779.          b->stipple_ximage = XCreateImage( xmesa->display,
  1780.                                            xmesa->xm_visual->visinfo->visual,
  1781.                                            1, ZPixmap, 0,
  1782.                                            (char *)ctx->PolygonStipple,
  1783.                                            32, 32, 8, 0 );
  1784.          b->stipple_ximage->byte_order = LSBFirst;
  1785.          b->stipple_ximage->bitmap_bit_order = LSBFirst;
  1786.          b->stipple_ximage->bitmap_unit = 32;
  1787.       }
  1788.  
  1789.       /*
  1790.        * NOTE: We don't handle the following here!
  1791.        *    GL_UNPACK_SWAP_BYTES
  1792.        *    GL_UNPACK_LSB_FIRST
  1793.        */
  1794.       XPutImage( xmesa->display,
  1795.          xmesa->xm_buffer->stipple_pixmap,
  1796.          xmesa->xm_buffer->stipple_gc,
  1797.                  xmesa->xm_buffer->stipple_ximage, 0, 0, 0, 0, 32, 32 );
  1798.       XSetStipple( xmesa->display, xmesa->xm_buffer->gc1,
  1799.                    xmesa->xm_buffer->stipple_pixmap );
  1800.       XSetStipple( xmesa->display, xmesa->xm_buffer->gc2,
  1801.                    xmesa->xm_buffer->stipple_pixmap );
  1802.       fill_type = FillStippled;
  1803.    }
  1804.    else {
  1805.       fill_type = FillSolid;
  1806.    }
  1807.  
  1808.    XSetFillStyle( xmesa->display, xmesa->xm_buffer->gc1, fill_type );
  1809.    XSetFillStyle( xmesa->display, xmesa->xm_buffer->gc2, fill_type );
  1810. }
  1811.  
  1812.  
  1813.  
  1814. triangle_func xmesa_get_triangle_func( GLcontext *ctx )
  1815. {
  1816.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  1817.    int depth = xmesa->xm_visual->visinfo->depth;
  1818.  
  1819.    if (ctx->Polygon.SmoothFlag)     return NULL;
  1820.    if (ctx->Texture.Enabled)        return NULL;
  1821.  
  1822.    if (xmesa->xm_buffer->buffer==XIMAGE) {
  1823.       if (   ctx->Light.ShadeModel==GL_SMOOTH
  1824.           && ctx->RasterMask==DEPTH_BIT
  1825.           && ctx->Depth.Func==GL_LESS
  1826.           && ctx->Depth.Mask==GL_TRUE
  1827.           && ctx->Polygon.StippleFlag==GL_FALSE) {
  1828.          switch (xmesa->pixelformat) {
  1829.             case PF_TRUECOLOR:
  1830.            return smooth_TRUECOLOR_z_triangle;
  1831.             case PF_8A8B8G8R:
  1832.                return smooth_8A8B8G8R_z_triangle;
  1833.             case PF_8R8G8B:
  1834.                return smooth_8R8G8B_z_triangle;
  1835.             case PF_5R6G5B:
  1836.                return smooth_5R6G5B_z_triangle;
  1837.             case PF_HPCR:
  1838.            return smooth_HPCR_z_triangle;
  1839.             case PF_DITHER:
  1840.                return (depth==8) ? smooth_DITHER8_z_triangle
  1841.                                         : smooth_DITHER_z_triangle;
  1842.             case PF_LOOKUP:
  1843.                return (depth==8) ? smooth_LOOKUP8_z_triangle : NULL;
  1844.             default:
  1845.                return NULL;
  1846.          }
  1847.       }
  1848.       if (   ctx->Light.ShadeModel==GL_FLAT
  1849.           && ctx->RasterMask==DEPTH_BIT
  1850.           && ctx->Depth.Func==GL_LESS
  1851.           && ctx->Depth.Mask==GL_TRUE
  1852.           && ctx->Polygon.StippleFlag==GL_FALSE) {
  1853.          switch (xmesa->pixelformat) {
  1854.             case PF_TRUECOLOR:
  1855.            return flat_TRUECOLOR_z_triangle;
  1856.             case PF_8A8B8G8R:
  1857.                return flat_8A8B8G8R_z_triangle;
  1858.             case PF_8R8G8B:
  1859.                return flat_8R8G8B_z_triangle;
  1860.             case PF_5R6G5B:
  1861.                return flat_5R6G5B_z_triangle;
  1862.             case PF_HPCR:
  1863.            return flat_HPCR_z_triangle;
  1864.             case PF_DITHER:
  1865.                return (depth==8) ? flat_DITHER8_z_triangle
  1866.                                         : flat_DITHER_z_triangle;
  1867.             case PF_LOOKUP:
  1868.                return (depth==8) ? flat_LOOKUP8_z_triangle : NULL;
  1869.             default:
  1870.                return NULL;
  1871.          }
  1872.       }
  1873.       if (   ctx->RasterMask==0   /* no depth test */
  1874.           && ctx->Light.ShadeModel==GL_SMOOTH
  1875.           && ctx->Polygon.StippleFlag==GL_FALSE) {
  1876.          switch (xmesa->pixelformat) {
  1877.             case PF_TRUECOLOR:
  1878.            return smooth_TRUECOLOR_triangle;
  1879.             case PF_8A8B8G8R:
  1880.                return smooth_8A8B8G8R_triangle;
  1881.             case PF_8R8G8B:
  1882.                return smooth_8R8G8B_triangle;
  1883.             case PF_5R6G5B:
  1884.                return smooth_5R6G5B_triangle;
  1885.             case PF_HPCR:
  1886.            return smooth_HPCR_triangle;
  1887.             case PF_DITHER:
  1888.                return (depth==8) ? smooth_DITHER8_triangle
  1889.                                         : smooth_DITHER_triangle;
  1890.             case PF_LOOKUP:
  1891.                return (depth==8) ? smooth_LOOKUP8_triangle : NULL;
  1892.             default:
  1893.                return NULL;
  1894.          }
  1895.       }
  1896.  
  1897.       if (   ctx->RasterMask==0   /* no depth test */
  1898.           && ctx->Light.ShadeModel==GL_FLAT
  1899.           && ctx->Polygon.StippleFlag==GL_FALSE) {
  1900.          switch (xmesa->pixelformat) {
  1901.             case PF_TRUECOLOR:
  1902.            return flat_TRUECOLOR_triangle;
  1903.             case PF_8A8B8G8R:
  1904.                return flat_8A8B8G8R_triangle;
  1905.             case PF_8R8G8B:
  1906.                return flat_8R8G8B_triangle;
  1907.             case PF_5R6G5B:
  1908.                return flat_5R6G5B_triangle;
  1909.             case PF_HPCR:
  1910.            return flat_HPCR_triangle;
  1911.             case PF_DITHER:
  1912.                return (depth==8) ? flat_DITHER8_triangle
  1913.                                         : flat_DITHER_triangle;
  1914.             case PF_LOOKUP:
  1915.                return (depth==8) ? flat_LOOKUP8_triangle : NULL;
  1916.             default:
  1917.                return NULL;
  1918.          }
  1919.       }
  1920.  
  1921.       return NULL;
  1922.    }
  1923.    else {
  1924.       /* pixmap */
  1925.       if (ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0) {
  1926.          setup_x_polygon_options( ctx );
  1927.          return flat_pixmap_triangle;
  1928.       }
  1929.       return NULL;
  1930.    }
  1931. }
  1932.  
  1933.